package com.rk.recommand;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 输入数据
 * 1,101,5.0
 */
public class UserCF_Step1{

    // step1的mapper
    public static class Step1Mapper extends Mapper<LongWritable, Text, Text, Text> {

        Text k = new Text();
        Text v = new Text();

        @Override
        protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
            String line = value.toString();
            String[] words = CommonConst.DELIMITER.split(line);
            if(words.length >= 3){
                String itemId = words[1];
                k.set(itemId);
                v.set(words[0] + "," + words[2]);  // userId + score
                context.write(k, v);
            }
        }
    }

    // step1的reducer
    public static class Step1Reducer extends Reducer<Text, Text, Text, Text>{

        Text k = new Text();
        Text v = new Text();

        @Override
        protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {

            Map<String, String> map = new HashMap<String, String>();

            for(Text value : values){
                String data = value.toString();
                String[] words = CommonConst.DELIMITER.split(data);
                if(words.length >= 2){
                    // 将数据转为map
                    map.put(words[0], words[1]);
                }
            }

            Iterator<String> iterA = map.keySet().iterator();
            while (iterA.hasNext()){
                String k1 = iterA.next();
                String v1 = map.get(k1);

                Iterator<String> iterB = map.keySet().iterator();
                while (iterB.hasNext()){
                    String k2 = iterB.next();
                    String v2 = map.get(k2);
                    k.set(k1 + "," + k2);
                    v.set(v1 + "," + v2);
                    context.write(k, v);
                }
            }
        }
    }

    public static void run(Map<String, String> paths) throws IOException, ClassNotFoundException, InterruptedException, URISyntaxException {
        Configuration configuration = new Configuration();
        System.setProperty("HADOOP_USER_NAME", "root");
        configuration.set("mapreduce.job.jar", "D:\\projects\\hadoop-study\\target\\hadoop-study-1.0-SNAPSHOT-jar-with-dependencies.jar");
        configuration.set("mapreduce.app-submission.cross-platform", "true");//意思是跨平台提交

        String input = paths.get("input_step1");
        String output = paths.get("output_step1");

        // YARN运行
        HDFSClient client = new HDFSClient();
        client.rmr(paths.get("input_file"));
        client.rmr(input);
        client.mkdirs(input);
        client.uploadFile(paths.get("data"), input);


        // 本地运行的话 无需在hdfs创建目录 否则需要使用hdfs API
        Job job = Job.getInstance(configuration, "UserCF_Step1 job");
        job.setJarByClass(UserCF_Step1.class);
        job.setMapperClass(Step1Mapper.class);
        job.setReducerClass(Step1Reducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);

        FileInputFormat.setInputPaths(job, new Path(input));
        FileOutputFormat.setOutputPath(job, new Path(output));

        boolean result = job.waitForCompletion(true);
        if(result){
            System.out.println("UserCF_Step1 run successful");
        }else {
            System.out.println("UserCF_Step1 run failed");
        }
    }
}
